use crate::ecs::entity::Entity;
use crate::scene_manager::SceneConfig;
use anyhow::Result;
use serde::Deserialize;
use std::collections::HashMap;
use std::fs;
use std::path::Path;

#[derive(Deserialize, Debug)]
pub struct Sprite {
    pub name: String,
    pub frames: Vec<String>,
    pub frame_rate: f32,
}

#[derive(Deserialize, Debug)]
pub struct EntityConfig {
    pub name: String,
    pub components: HashMap<String, serde_json::Value>,
}

pub struct AssetManager {
    pub sprites: HashMap<String, Sprite>,
    pub entities: HashMap<String, Entity>,
    pub scenes: HashMap<String, SceneConfig>,
}

impl AssetManager {
    pub fn new() -> Self {
        Self {
            sprites: HashMap::new(),
            entities: HashMap::new(),
            scenes: HashMap::new(),
        }
    }
    
    pub fn load_assets(&mut self, asset_dir: &str) -> Result<()> {
        self.load_sprites(&format!("{}/sprites", asset_dir))?;
        self.load_entities(&format!("{}/entities", asset_dir))?;
        self.load_scenes(&format!("{}/scenes", asset_dir))?;
        Ok(())
    }
    
    fn load_sprites(&mut self, dir: &str) -> Result<()> {
        if !Path::new(dir).exists() {
            return Ok(());
        }
        
        for entry in fs::read_dir(dir)? {
            let entry = entry?;
            let path = entry.path();
            if path.is_file() && path.extension().map(|e| e == "json").unwrap_or(false) {
                let content = fs::read_to_string(&path)?;
                let sprite: Sprite = serde_json::from_str(&content)?;
                self.sprites.insert(sprite.name.clone(), sprite);
            }
        }
        Ok(())
    }
    
    fn load_entities(&mut self, dir: &str) -> Result<()> {
        if !Path::new(dir).exists() {
            return Ok(());
        }
        
        for entry in fs::read_dir(dir)? {
            let entry = entry?;
            let path = entry.path();
            if path.is_file() && path.extension().map(|e| e == "json").unwrap_or(false) {
                let content = fs::read_to_string(&path)?;
                let config: EntityConfig = serde_json::from_str(&content)?;
                
                let entity = Entity::new(&config.name);
                self.entities.insert(config.name.clone(), entity);
            }
        }
        Ok(())
    }
    
    fn load_scenes(&mut self, dir: &str) -> Result<()> {
        if !Path::new(dir).exists() {
            return Ok(());
        }
        
        for entry in fs::read_dir(dir)? {
            let entry = entry?;
            let path = entry.path();
            if path.is_file() && path.extension().map(|e| e == "json").unwrap_or(false) {
                let content = fs::read_to_string(&path)?;
                let scene: SceneConfig = serde_json::from_str(&content)?;
                self.scenes.insert(scene.name.clone(), scene);
            }
        }
        Ok(())
    }
    
    pub fn get_sprite(&self, name: &str) -> Option<&Sprite> {
        self.sprites.get(name)
    }
    
    pub fn get_entity(&self, name: &str) -> Option<&Entity> {
        self.entities.get(name)
    }
    
    pub fn get_scene_config(&self, name: &str) -> Option<&SceneConfig> {
        self.scenes.get(name)
    }
}